home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / MCGA_TUT.ZIP / MCGA.06 < prev    next >
Encoding:
Text File  |  1995-08-31  |  9.3 KB  |  445 lines

  1. -------------------------------------------------------------------------------
  2. Nachricht Nr. 0271 aus Area PASCAL.GER   Exportiert mit Yuppie! v2.10
  3. -------------------------------------------------------------------------------
  4. Datum: 05 Jul 92  19:24:07
  5. Von  : Martin Austermeier                     
  6. An   : Thomas Karp                            
  7. Betr.: MCGA Tutorial #6                                                    
  8. -------------------------------------------------------------------------------
  9. Hallo Thomas,
  10.  
  11. vielen Dank für dein Posting. Teil #6 war nicht dabei, deshalb ..
  12.  
  13.  * Originally from:  James Cook  (05 Jun 92 22:05)  in area PASCAL
  14.  * Original subject: MCGA Tutorial #6
  15.  
  16.                            MCGA Graphics Tutorial
  17.                                  Lesson #6
  18.                                 by Jim Cook
  19.  
  20. I am including the MCGALIB source we have developed so far in this
  21. tutorial.
  22.  
  23. Unit MCGALib;
  24.  
  25. interface
  26.  
  27. type
  28.   PCXHeaderPtr=  ^PCXHeader;
  29.   PCXHeader   =  record
  30.                    Signature      :  Char;
  31.                    Version        :  Char;
  32.                    Encoding       :  Char;
  33.                    BitsPerPixel   :  Char;
  34.                    XMin,YMin,
  35.                    XMax,YMax      :  Integer;
  36.                    HRes,VRes      :  Integer;
  37.                    Palette        :  Array [0..47] of byte;
  38.                    Reserved       :  Char;
  39.                    Planes         :  Char;
  40.                    BytesPerLine   :  Integer;
  41.                    PaletteType    :  Integer;
  42.                    Filler         :  Array [0..57] of byte;
  43.                  end;
  44.  
  45.   PointerType =  array [0..65500] of byte;
  46.   NewPointer  =  ^PointerType;
  47.  
  48. var
  49.   ScreenWide  :  Integer;
  50.  
  51. Procedure SetGraphMode (Num:Byte);
  52. Procedure SetPixel     (X,Y:Integer;Color:Byte);
  53. Function  GetPixel     (X,Y:Integer) : Word;
  54. Procedure ClearScreen  (Color:Byte);
  55. Procedure Line         (X1,Y1,X2,Y2:Integer;Color:Byte);
  56. Procedure Box          (X1,Y1,X2,Y2:Integer;Color:Byte);
  57.  
  58. Procedure DisplayPCX   (X,Y:Integer;Buf:Pointer);
  59.  
  60. Function  ImageSize    (X1,Y1,X2,Y2:Integer) : Word;
  61. Procedure GetImagePas  (X1,Y1,X2,Y2:Integer;P:Pointer);
  62. Procedure PutImagePas  (X1,Y1:Integer;P:Pointer);
  63.  
  64. implementation
  65.  
  66. var
  67.   ScreenAddr  :  Word;
  68.  
  69. Procedure SetGraphMode (Num:Byte);
  70. begin
  71.   asm
  72.     mov al,Num
  73.     mov ah,0
  74.     int 10h
  75.     end;
  76.   Case Num of
  77.     $13 : ScreenWide := 320;
  78.     end;
  79.   ScreenAddr := $A000;
  80. end;
  81.  
  82. Procedure SetPixel (X,Y:Integer;Color:Byte);
  83. begin
  84.   asm
  85.     push ds
  86.     mov  ax,ScreenAddr
  87.     mov  ds,ax
  88.  
  89.     mov  ax,Y
  90.     mov  bx,320
  91.     mul  bx
  92.     mov  bx,X
  93.     add  bx,ax
  94.  
  95.     mov  al,Color
  96.     mov  byte ptr ds:[bx],al
  97.     pop  ds
  98.     end;
  99. end;
  100.  
  101. Function GetPixel (X,Y:Integer) : Word;
  102. begin
  103.   asm
  104.     push ds
  105.     mov  ax,ScreenAddr
  106.     mov  ds,ax
  107.  
  108.     mov  ax,Y
  109.     mov  bx,320
  110.     mul  bx
  111.     mov  bx,X
  112.     add  bx,ax
  113.  
  114.     xor  ax,ax
  115.     mov  al,byte ptr ds:[bx]
  116.     mov  @Result,ax
  117.     pop  ds
  118.     end;
  119. end;
  120.  
  121. Procedure ClearScreen (Color:Byte);
  122. begin
  123.   asm
  124.     push es
  125.     mov  ax,ScreenAddr
  126.     mov  es,ax
  127.  
  128.     xor  di,di
  129.  
  130.     mov  al,Color
  131.     mov  cx,320*200
  132.  
  133.     rep  stosb
  134.  
  135.     pop  es
  136.     end;
  137. end;
  138.  
  139. Procedure HorzLine (X1,X2,Y1:Integer;Color:Byte);
  140. var
  141.   Temp   :  Integer;
  142. begin
  143.   If X1 > X2 then begin
  144.     Temp := X1;
  145.     X1   := X2;
  146.     X2   := Temp;
  147.     end;
  148.   asm
  149.     push es
  150.     mov  ax,ScreenAddr
  151.     mov  es,ax               { Point es to screen segment }
  152.  
  153.     mov  ax,Y1               { Calculate starting video memory location }
  154.     mov  di,ScreenWide
  155.     mul  di                  { Multiply row number by width of screen }
  156.     mov  di,X1
  157.     add  di,ax               { Add to that result the X value }
  158.                              { Result: es:di -> first pixel to draw }
  159.     mov  cx,X2
  160.     sub  cx,X1
  161.     inc  cx                  { cx = number of pixels to draw }
  162.  
  163.     mov  al,Color            { put the color in al }
  164.  
  165.     rep  stosb               { use a fast 8088 instruction to store al }
  166.  
  167.     pop  es
  168.     end;
  169. end;
  170.  
  171. Procedure VertLine (X1,Y1,Y2:Integer;Color:Byte);
  172. var
  173.   Temp   :  Integer;
  174. begin
  175.   If Y1 > Y2 then begin
  176.     Temp := Y1;
  177.     Y1   := Y2;
  178.     Y2   := Temp;
  179.     end;
  180.   asm
  181.     push es
  182.     mov  ax,ScreenAddr
  183.     mov  es,ax               { Point es to screen segment }
  184.  
  185.     mov  ax,Y1               { Calculate starting video memory location }
  186.     mov  di,ScreenWide
  187.     mul  di                  { Multiply row number by width of screen }
  188.     mov  di,X1
  189.     add  di,ax               { Add to that result the X value }
  190.                              { Result: es:di -> first pixel to draw }
  191.     mov  cx,Y2
  192.     sub  cx,Y1
  193.     inc  cx                  { cx = number of pixels to draw }
  194.  
  195.     mov  al,Color            { put the color in al }
  196.  
  197. @Loop1:
  198.     mov  es:[di],al
  199.     add  di,ScreenWide
  200.     loop @Loop1
  201.  
  202.     pop  es
  203.     end;
  204. end;
  205.  
  206. Procedure Line (X1,Y1,X2,Y2:Integer;Color:Byte);
  207. var
  208.   I,
  209.   YIncr,
  210.   D,DX,DY,
  211.   AIncr,BIncr :  Integer;
  212.   Ofs         :  Word;
  213. begin                                  { uses Bresenham's algorithm for }
  214.   If X1 = X2 then begin                { drawing a line.  Very fast for }
  215.     VertLine (X1,Y1,Y2,Color);         { little ol' Pascal              }
  216.     Exit;
  217.     end;
  218.   If Y1 = Y2 then begin
  219.     HorzLine (X1,X2,Y2,Color);
  220.     Exit;
  221.     end;
  222.   If X1 > X2 then begin
  223.     D  := X1;
  224.     X1 := X2;
  225.     X2 := D;
  226.     D  := Y1;
  227.     Y1 := Y2;
  228.     Y2 := D;
  229.     end;
  230.   If Y2 > Y1 then YIncr :=  320
  231.              else YIncr := -320;
  232.   DX := X2 - X1;
  233.   DY := Abs (Y2-Y1);
  234.   D := 2 * DY - DX;
  235.   AIncr := 2 * (DY - DX);
  236.   BIncr := 2 * DY;
  237.  
  238.  
  239.   Ofs := Word(Y1) * 320 + Word(X1);
  240.  
  241.   Mem [$A000:Ofs] := Color;
  242.  
  243.   For I := X1 + 1 to X2 do begin
  244.     If D >= 0 then begin
  245.       Inc (Ofs,YIncr);
  246.       Inc (D,AIncr);
  247.       end
  248.     Else Inc (D,BIncr);
  249.     Inc (Ofs);
  250.     Mem [$A000:Ofs] := Color;
  251.     end;
  252. end;
  253.  
  254. Procedure Box (X1,Y1,X2,Y2:Integer;Color:Byte);
  255. var
  256.   Y :  Integer;
  257. begin
  258.   For Y := Y1 to Y2 do
  259.     HorzLine (X1,X2,Y,Color);
  260. end;
  261.  
  262. Procedure ExtractLineASM (BytesWide:Integer;Var Source,Dest:Pointer);
  263. var
  264.   DestSeg,
  265.   DestOfs,
  266.   SourceSeg,
  267.   SourceOfs   :  Word;
  268. begin
  269.   SourceSeg := Seg (Source^);
  270.   SourceOfs := Ofs (Source^);
  271.   DestSeg   := Seg (Dest^);
  272.   DestOfs   := Ofs (Dest^);
  273.  
  274.   asm
  275.     push  ds
  276.     push  si
  277.  
  278.     mov   ax,DestSeg
  279.     mov   es,ax
  280.     mov   di,DestOfs     { es:di -> destination pointer }
  281.     mov   ax,SourceSeg
  282.     mov   ds,ax
  283.     mov   si,SourceOfs   { ds:si -> source buffer }
  284.  
  285.     mov   bx,di
  286.     add   bx,BytesWide   { bx holds position to stop for this row }
  287.     xor   cx,cx
  288.  
  289.   @@GetNextByte:
  290.     cmp   bx,di          { are we done with the line }
  291.     jbe   @@ExitHere
  292.  
  293.     lodsb                { al contains next byte }
  294.  
  295.     mov   ah,al
  296.     and   ah,0C0h
  297.     cmp   ah,0C0h
  298.     jne   @@SingleByte
  299.                          { must be a run of bytes }
  300.     mov   cl,al
  301.     and   cl,3Fh
  302.     lodsb
  303.     rep   stosb
  304.     jmp   @@GetNextByte
  305.  
  306.   @@SingleByte:
  307.     stosb
  308.     jmp   @@GetNextByte
  309.  
  310.   @@ExitHere:
  311.     mov   SourceSeg,ds
  312.     mov   SourceOfs,si
  313.     mov   DestSeg,es
  314.     mov   DestOfs,di
  315.  
  316.     pop   si
  317.     pop   ds
  318.   end;
  319.  
  320.   If Odd(BytesWide) then Source := Ptr (SourceSeg,SourceOfs+2)
  321.                     else Source := Ptr (SourceSeg,SourceOfs);
  322.  
  323.   Dest := Ptr (DestSeg,DestOfs);
  324. end;
  325.  
  326. Procedure DisplayPCX (X,Y:Integer;Buf:Pointer);
  327. var
  328.   I,NumRows,
  329.   BytesWide   :  Integer;
  330.   Header      :  PCXHeaderPtr;
  331.   DestPtr     :  Pointer;
  332.   Offset      :  Word;
  333. begin
  334.   Header    := Ptr (Seg(Buf^),Ofs(Buf^));
  335.   Buf       := Ptr (Seg(Buf^),Ofs(Buf^)+128);
  336.   Offset    := Y * 320 + X;
  337.   NumRows   := Header^.YMax - Header^.YMin + 1;
  338.   BytesWide := Header^.XMax - Header^.XMin + 1;
  339.  
  340.   For I := 1 to NumRows do begin
  341.     DestPtr := Ptr ($A000,Offset);
  342.     ExtractLineASM (BytesWide,Buf,DestPtr);
  343.     Inc (Offset,320);
  344.     end;
  345. end;
  346.  
  347. Function ImageSize (X1,Y1,X2,Y2:Integer) : Word;
  348. begin
  349.   ImageSize := Word(Y2 - Y1 + 1) * Word(X2 - X1 + 1) + 4;
  350. end;
  351.  
  352. Procedure GetImageAsm (X1,Y1,X2,Y2:Integer;P:Pointer); assembler;
  353. asm
  354.     mov  bx,ScreenWide
  355.     push ds
  356.     les  di,P
  357.  
  358.     mov  ax,0A000h
  359.     mov  ds,ax
  360.     mov  ax,Y1
  361.     mov  dx,320
  362.     mul  dx
  363.     add  ax,X1
  364.     mov  si,ax
  365.  
  366.     mov  ax,X2
  367.     sub  ax,X1
  368.     inc  ax
  369.     mov  dx,ax
  370.     stosw
  371.  
  372.     mov  ax,Y2
  373.     sub  ax,Y1
  374.     inc  ax
  375.     stosw
  376.     mov  cx,ax
  377.  
  378.   @@1:
  379.     mov  cx,dx
  380.  
  381.     shr  cx,1
  382.     rep  movsw
  383.  
  384.     test dx,1
  385.     jz   @@2
  386.     movsb
  387.   @@2:
  388.     add  si,bx
  389.     sub  si,dx
  390.  
  391.     dec  ax
  392.     jnz  @@1
  393.  
  394.     pop  ds
  395. end;
  396.  
  397. Procedure PutImageAsm (X1,Y1:Integer;P:Pointer); assembler;
  398. asm
  399.     mov  bx,ScreenWide
  400.     push ds
  401.     lds  si,P
  402.  
  403.     mov  ax,0A000h
  404.     mov  es,ax
  405.     mov  ax,Y1
  406.     mov  dx,320
  407.     mul  dx
  408.     add  ax,X1
  409.     mov  di,ax
  410.  
  411.     lodsw
  412.     mov  dx,ax
  413.  
  414.     lodsw
  415.  
  416.   @@1:
  417.     mov  cx,dx
  418.  
  419.     shr  cx,1
  420.     rep  movsw
  421.  
  422.     test dx,1
  423.     jz   @@2
  424.     movsb
  425.   @@2:
  426.     add  di,bx
  427.     sub  di,dx
  428.  
  429.     dec  ax
  430.     jnz  @@1
  431.  
  432.     pop  ds
  433. end;
  434.  
  435. Begin
  436. End.
  437.  
  438. ... That tagline is TRUE ->  <- That tagline is FALSE
  439. --- Blue Wave/QBBS v2.05 [NR]
  440.  * Origin: Quantum Leap BBS.. (512)333-5360  v.32bis  (1:387/307) (1:387/307.0)
  441.  * End of forwarded message
  442.  
  443. --- Yuppie! v2.10
  444.  * Origin: Das Wirth'shaus am Datenfluss (2:244/20.15)
  445.